//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension VoiceID {
    // MARK: Enums

    public enum AuthenticationDecision: String, CustomStringConvertible, Codable, _SotoSendable {
        case accept = "ACCEPT"
        case notEnoughSpeech = "NOT_ENOUGH_SPEECH"
        case reject = "REJECT"
        case speakerExpired = "SPEAKER_EXPIRED"
        case speakerIdNotProvided = "SPEAKER_ID_NOT_PROVIDED"
        case speakerNotEnrolled = "SPEAKER_NOT_ENROLLED"
        case speakerOptedOut = "SPEAKER_OPTED_OUT"
        public var description: String { return self.rawValue }
    }

    public enum DomainStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case active = "ACTIVE"
        case pending = "PENDING"
        case suspended = "SUSPENDED"
        public var description: String { return self.rawValue }
    }

    public enum DuplicateRegistrationAction: String, CustomStringConvertible, Codable, _SotoSendable {
        case registerAsNew = "REGISTER_AS_NEW"
        case skip = "SKIP"
        public var description: String { return self.rawValue }
    }

    public enum ExistingEnrollmentAction: String, CustomStringConvertible, Codable, _SotoSendable {
        case overwrite = "OVERWRITE"
        case skip = "SKIP"
        public var description: String { return self.rawValue }
    }

    public enum FraudDetectionAction: String, CustomStringConvertible, Codable, _SotoSendable {
        case fail = "FAIL"
        case ignore = "IGNORE"
        public var description: String { return self.rawValue }
    }

    public enum FraudDetectionDecision: String, CustomStringConvertible, Codable, _SotoSendable {
        case highRisk = "HIGH_RISK"
        case lowRisk = "LOW_RISK"
        case notEnoughSpeech = "NOT_ENOUGH_SPEECH"
        public var description: String { return self.rawValue }
    }

    public enum FraudDetectionReason: String, CustomStringConvertible, Codable, _SotoSendable {
        case knownFraudster = "KNOWN_FRAUDSTER"
        case voiceSpoofing = "VOICE_SPOOFING"
        public var description: String { return self.rawValue }
    }

    public enum FraudsterRegistrationJobStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case completed = "COMPLETED"
        case completedWithErrors = "COMPLETED_WITH_ERRORS"
        case failed = "FAILED"
        case inProgress = "IN_PROGRESS"
        case submitted = "SUBMITTED"
        public var description: String { return self.rawValue }
    }

    public enum ServerSideEncryptionUpdateStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case completed = "COMPLETED"
        case failed = "FAILED"
        case inProgress = "IN_PROGRESS"
        public var description: String { return self.rawValue }
    }

    public enum SpeakerEnrollmentJobStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case completed = "COMPLETED"
        case completedWithErrors = "COMPLETED_WITH_ERRORS"
        case failed = "FAILED"
        case inProgress = "IN_PROGRESS"
        case submitted = "SUBMITTED"
        public var description: String { return self.rawValue }
    }

    public enum SpeakerStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case enrolled = "ENROLLED"
        case expired = "EXPIRED"
        case optedOut = "OPTED_OUT"
        case pending = "PENDING"
        public var description: String { return self.rawValue }
    }

    public enum StreamingStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case ended = "ENDED"
        case ongoing = "ONGOING"
        case pendingConfiguration = "PENDING_CONFIGURATION"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AuthenticationConfiguration: AWSDecodableShape {
        /// The minimum threshold needed to successfully authenticate a speaker.
        public let acceptanceThreshold: Int

        public init(acceptanceThreshold: Int) {
            self.acceptanceThreshold = acceptanceThreshold
        }

        private enum CodingKeys: String, CodingKey {
            case acceptanceThreshold = "AcceptanceThreshold"
        }
    }

    public struct AuthenticationResult: AWSDecodableShape {
        /// A timestamp indicating when audio aggregation ended for this authentication result.
        public let audioAggregationEndedAt: Date?
        /// A timestamp indicating when audio aggregation started for this authentication result.
        public let audioAggregationStartedAt: Date?
        /// The unique identifier for this authentication result. Because there can be multiple authentications for a given session, this field helps to identify if the returned result is from a previous streaming activity or a new result. Note that in absence of any new streaming activity, AcceptanceThreshold changes, or SpeakerId changes, Voice ID always returns cached Authentication Result for this API.
        public let authenticationResultId: String?
        /// The AuthenticationConfiguration used to generate this authentication result.
        public let configuration: AuthenticationConfiguration?
        /// The client-provided identifier for the speaker whose authentication result is produced. Only present if a SpeakerId is provided for the session.
        public let customerSpeakerId: String?
        /// The authentication decision produced by Voice ID, processed against the current session state and streamed audio of the speaker.
        public let decision: AuthenticationDecision?
        /// The service-generated identifier for the speaker whose authentication result is produced.
        public let generatedSpeakerId: String?
        /// The authentication score for the speaker whose authentication result is produced. This value is only present if the authentication decision is either ACCEPT or REJECT.
        public let score: Int?

        public init(audioAggregationEndedAt: Date? = nil, audioAggregationStartedAt: Date? = nil, authenticationResultId: String? = nil, configuration: AuthenticationConfiguration? = nil, customerSpeakerId: String? = nil, decision: AuthenticationDecision? = nil, generatedSpeakerId: String? = nil, score: Int? = nil) {
            self.audioAggregationEndedAt = audioAggregationEndedAt
            self.audioAggregationStartedAt = audioAggregationStartedAt
            self.authenticationResultId = authenticationResultId
            self.configuration = configuration
            self.customerSpeakerId = customerSpeakerId
            self.decision = decision
            self.generatedSpeakerId = generatedSpeakerId
            self.score = score
        }

        private enum CodingKeys: String, CodingKey {
            case audioAggregationEndedAt = "AudioAggregationEndedAt"
            case audioAggregationStartedAt = "AudioAggregationStartedAt"
            case authenticationResultId = "AuthenticationResultId"
            case configuration = "Configuration"
            case customerSpeakerId = "CustomerSpeakerId"
            case decision = "Decision"
            case generatedSpeakerId = "GeneratedSpeakerId"
            case score = "Score"
        }
    }

    public struct CreateDomainRequest: AWSEncodableShape {
        /// The idempotency token for creating a new domain. If not provided, Amazon Web Services SDK populates this field.
        public let clientToken: String?
        /// A brief description of the domain.
        public let description: String?
        /// The name of the domain.
        public let name: String
        /// The configuration, containing the KMS key identifier, to be used by Voice ID for the server-side encryption of your data. Refer to  Amazon Connect Voice ID encryption at rest for more details on how the KMS key is used.
        public let serverSideEncryptionConfiguration: ServerSideEncryptionConfiguration
        /// A list of tags you want added to the domain.
        public let tags: [Tag]?

        public init(clientToken: String? = CreateDomainRequest.idempotencyToken(), description: String? = nil, name: String, serverSideEncryptionConfiguration: ServerSideEncryptionConfiguration, tags: [Tag]? = nil) {
            self.clientToken = clientToken
            self.description = description
            self.name = name
            self.serverSideEncryptionConfiguration = serverSideEncryptionConfiguration
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[a-zA-Z0-9-_]+$")
            try self.validate(self.description, name: "description", parent: name, max: 1024)
            try self.validate(self.description, name: "description", parent: name, min: 1)
            try self.validate(self.description, name: "description", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
            try self.validate(self.name, name: "name", parent: name, max: 256)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9][a-zA-Z0-9_-]*$")
            try self.serverSideEncryptionConfiguration.validate(name: "\(name).serverSideEncryptionConfiguration")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case description = "Description"
            case name = "Name"
            case serverSideEncryptionConfiguration = "ServerSideEncryptionConfiguration"
            case tags = "Tags"
        }
    }

    public struct CreateDomainResponse: AWSDecodableShape {
        /// Information about the newly created domain.
        public let domain: Domain?

        public init(domain: Domain? = nil) {
            self.domain = domain
        }

        private enum CodingKeys: String, CodingKey {
            case domain = "Domain"
        }
    }

    public struct DeleteDomainRequest: AWSEncodableShape {
        /// The identifier of the domain you want to delete.
        public let domainId: String

        public init(domainId: String) {
            self.domainId = domainId
        }

        public func validate(name: String) throws {
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
        }

        private enum CodingKeys: String, CodingKey {
            case domainId = "DomainId"
        }
    }

    public struct DeleteFraudsterRequest: AWSEncodableShape {
        /// The identifier of the domain containing the fraudster.
        public let domainId: String
        /// The identifier of the fraudster you want to delete.
        public let fraudsterId: String

        public init(domainId: String, fraudsterId: String) {
            self.domainId = domainId
            self.fraudsterId = fraudsterId
        }

        public func validate(name: String) throws {
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
            try self.validate(self.fraudsterId, name: "fraudsterId", parent: name, max: 25)
            try self.validate(self.fraudsterId, name: "fraudsterId", parent: name, min: 25)
            try self.validate(self.fraudsterId, name: "fraudsterId", parent: name, pattern: "^id#[a-zA-Z0-9]{22}$")
        }

        private enum CodingKeys: String, CodingKey {
            case domainId = "DomainId"
            case fraudsterId = "FraudsterId"
        }
    }

    public struct DeleteSpeakerRequest: AWSEncodableShape {
        /// The identifier of the domain containing the speaker.
        public let domainId: String
        /// The identifier of the speaker you want to delete.
        public let speakerId: String

        public init(domainId: String, speakerId: String) {
            self.domainId = domainId
            self.speakerId = speakerId
        }

        public func validate(name: String) throws {
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
            try self.validate(self.speakerId, name: "speakerId", parent: name, max: 256)
            try self.validate(self.speakerId, name: "speakerId", parent: name, min: 1)
            try self.validate(self.speakerId, name: "speakerId", parent: name, pattern: "^(id#[a-zA-Z0-9]{22}|[a-zA-Z0-9][a-zA-Z0-9_-]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case domainId = "DomainId"
            case speakerId = "SpeakerId"
        }
    }

    public struct DescribeDomainRequest: AWSEncodableShape {
        /// The identifier of the domain you are describing.
        public let domainId: String

        public init(domainId: String) {
            self.domainId = domainId
        }

        public func validate(name: String) throws {
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
        }

        private enum CodingKeys: String, CodingKey {
            case domainId = "DomainId"
        }
    }

    public struct DescribeDomainResponse: AWSDecodableShape {
        /// Information about the specified domain.
        public let domain: Domain?

        public init(domain: Domain? = nil) {
            self.domain = domain
        }

        private enum CodingKeys: String, CodingKey {
            case domain = "Domain"
        }
    }

    public struct DescribeFraudsterRegistrationJobRequest: AWSEncodableShape {
        /// The identifier for the domain containing the fraudster registration job.
        public let domainId: String
        /// The identifier for the fraudster registration job you are describing.
        public let jobId: String

        public init(domainId: String, jobId: String) {
            self.domainId = domainId
            self.jobId = jobId
        }

        public func validate(name: String) throws {
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
            try self.validate(self.jobId, name: "jobId", parent: name, max: 22)
            try self.validate(self.jobId, name: "jobId", parent: name, min: 22)
            try self.validate(self.jobId, name: "jobId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
        }

        private enum CodingKeys: String, CodingKey {
            case domainId = "DomainId"
            case jobId = "JobId"
        }
    }

    public struct DescribeFraudsterRegistrationJobResponse: AWSDecodableShape {
        /// Contains details about the specified fraudster registration job.
        public let job: FraudsterRegistrationJob?

        public init(job: FraudsterRegistrationJob? = nil) {
            self.job = job
        }

        private enum CodingKeys: String, CodingKey {
            case job = "Job"
        }
    }

    public struct DescribeFraudsterRequest: AWSEncodableShape {
        /// The identifier of the domain containing the fraudster.
        public let domainId: String
        /// The identifier of the fraudster you are describing.
        public let fraudsterId: String

        public init(domainId: String, fraudsterId: String) {
            self.domainId = domainId
            self.fraudsterId = fraudsterId
        }

        public func validate(name: String) throws {
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
            try self.validate(self.fraudsterId, name: "fraudsterId", parent: name, max: 25)
            try self.validate(self.fraudsterId, name: "fraudsterId", parent: name, min: 25)
            try self.validate(self.fraudsterId, name: "fraudsterId", parent: name, pattern: "^id#[a-zA-Z0-9]{22}$")
        }

        private enum CodingKeys: String, CodingKey {
            case domainId = "DomainId"
            case fraudsterId = "FraudsterId"
        }
    }

    public struct DescribeFraudsterResponse: AWSDecodableShape {
        /// Information about the specified fraudster.
        public let fraudster: Fraudster?

        public init(fraudster: Fraudster? = nil) {
            self.fraudster = fraudster
        }

        private enum CodingKeys: String, CodingKey {
            case fraudster = "Fraudster"
        }
    }

    public struct DescribeSpeakerEnrollmentJobRequest: AWSEncodableShape {
        /// The identifier of the domain containing the speaker enrollment job.
        public let domainId: String
        /// The identifier of the speaker enrollment job you are describing.
        public let jobId: String

        public init(domainId: String, jobId: String) {
            self.domainId = domainId
            self.jobId = jobId
        }

        public func validate(name: String) throws {
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
            try self.validate(self.jobId, name: "jobId", parent: name, max: 22)
            try self.validate(self.jobId, name: "jobId", parent: name, min: 22)
            try self.validate(self.jobId, name: "jobId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
        }

        private enum CodingKeys: String, CodingKey {
            case domainId = "DomainId"
            case jobId = "JobId"
        }
    }

    public struct DescribeSpeakerEnrollmentJobResponse: AWSDecodableShape {
        /// Contains details about the specified speaker enrollment job.
        public let job: SpeakerEnrollmentJob?

        public init(job: SpeakerEnrollmentJob? = nil) {
            self.job = job
        }

        private enum CodingKeys: String, CodingKey {
            case job = "Job"
        }
    }

    public struct DescribeSpeakerRequest: AWSEncodableShape {
        /// The identifier of the domain that contains the speaker.
        public let domainId: String
        /// The identifier of the speaker you are describing.
        public let speakerId: String

        public init(domainId: String, speakerId: String) {
            self.domainId = domainId
            self.speakerId = speakerId
        }

        public func validate(name: String) throws {
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
            try self.validate(self.speakerId, name: "speakerId", parent: name, max: 256)
            try self.validate(self.speakerId, name: "speakerId", parent: name, min: 1)
            try self.validate(self.speakerId, name: "speakerId", parent: name, pattern: "^(id#[a-zA-Z0-9]{22}|[a-zA-Z0-9][a-zA-Z0-9_-]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case domainId = "DomainId"
            case speakerId = "SpeakerId"
        }
    }

    public struct DescribeSpeakerResponse: AWSDecodableShape {
        /// Information about the specified speaker.
        public let speaker: Speaker?

        public init(speaker: Speaker? = nil) {
            self.speaker = speaker
        }

        private enum CodingKeys: String, CodingKey {
            case speaker = "Speaker"
        }
    }

    public struct Domain: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) for the domain.
        public let arn: String?
        /// The timestamp at which the domain is created.
        public let createdAt: Date?
        /// The client-provided description of the domain.
        public let description: String?
        /// The service-generated identifier for the domain.
        public let domainId: String?
        /// The current status of the domain.
        public let domainStatus: DomainStatus?
        /// The client-provided name for the domain.
        public let name: String?
        /// The server-side encryption configuration containing the KMS key identifier you want Voice ID to use to encrypt your data.
        public let serverSideEncryptionConfiguration: ServerSideEncryptionConfiguration?
        /// Details about the most recent server-side encryption configuration update. When the server-side encryption configuration is changed, dependency on the old KMS key is removed through an asynchronous process. When this update is complete, the domain's data can only be accessed using the new KMS key.
        public let serverSideEncryptionUpdateDetails: ServerSideEncryptionUpdateDetails?
        /// The timestamp showing the domain's last update.
        public let updatedAt: Date?

        public init(arn: String? = nil, createdAt: Date? = nil, description: String? = nil, domainId: String? = nil, domainStatus: DomainStatus? = nil, name: String? = nil, serverSideEncryptionConfiguration: ServerSideEncryptionConfiguration? = nil, serverSideEncryptionUpdateDetails: ServerSideEncryptionUpdateDetails? = nil, updatedAt: Date? = nil) {
            self.arn = arn
            self.createdAt = createdAt
            self.description = description
            self.domainId = domainId
            self.domainStatus = domainStatus
            self.name = name
            self.serverSideEncryptionConfiguration = serverSideEncryptionConfiguration
            self.serverSideEncryptionUpdateDetails = serverSideEncryptionUpdateDetails
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case createdAt = "CreatedAt"
            case description = "Description"
            case domainId = "DomainId"
            case domainStatus = "DomainStatus"
            case name = "Name"
            case serverSideEncryptionConfiguration = "ServerSideEncryptionConfiguration"
            case serverSideEncryptionUpdateDetails = "ServerSideEncryptionUpdateDetails"
            case updatedAt = "UpdatedAt"
        }
    }

    public struct DomainSummary: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) for the domain.
        public let arn: String?
        /// The timestamp showing when the domain is created.
        public let createdAt: Date?
        /// The client-provided description of the domain.
        public let description: String?
        /// The service-generated identifier for the domain.
        public let domainId: String?
        /// The current status of the domain.
        public let domainStatus: DomainStatus?
        /// The client-provided name for the domain.
        public let name: String?
        /// The server-side encryption configuration containing the KMS key identifier you want Voice ID to use to encrypt your data.
        public let serverSideEncryptionConfiguration: ServerSideEncryptionConfiguration?
        /// Details about the most recent server-side encryption configuration update. When the server-side encryption configuration is changed, dependency on the old KMS key is removed through an asynchronous process. When this update is complete, the domain's data can only be accessed using the new KMS key.
        public let serverSideEncryptionUpdateDetails: ServerSideEncryptionUpdateDetails?
        /// The timestamp showing the domain's last update.
        public let updatedAt: Date?

        public init(arn: String? = nil, createdAt: Date? = nil, description: String? = nil, domainId: String? = nil, domainStatus: DomainStatus? = nil, name: String? = nil, serverSideEncryptionConfiguration: ServerSideEncryptionConfiguration? = nil, serverSideEncryptionUpdateDetails: ServerSideEncryptionUpdateDetails? = nil, updatedAt: Date? = nil) {
            self.arn = arn
            self.createdAt = createdAt
            self.description = description
            self.domainId = domainId
            self.domainStatus = domainStatus
            self.name = name
            self.serverSideEncryptionConfiguration = serverSideEncryptionConfiguration
            self.serverSideEncryptionUpdateDetails = serverSideEncryptionUpdateDetails
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case createdAt = "CreatedAt"
            case description = "Description"
            case domainId = "DomainId"
            case domainStatus = "DomainStatus"
            case name = "Name"
            case serverSideEncryptionConfiguration = "ServerSideEncryptionConfiguration"
            case serverSideEncryptionUpdateDetails = "ServerSideEncryptionUpdateDetails"
            case updatedAt = "UpdatedAt"
        }
    }

    public struct EnrollmentConfig: AWSEncodableShape & AWSDecodableShape {
        ///  The action to take when the specified speaker is already enrolled in the specified domain. The default value is SKIP, which skips the enrollment for the existing speaker. Setting the value to OVERWRITE replaces the existing voice prints and enrollment audio stored for that speaker with new data generated from the latest audio.
        public let existingEnrollmentAction: ExistingEnrollmentAction?
        /// The fraud detection configuration to use for the speaker enrollment job.
        public let fraudDetectionConfig: EnrollmentJobFraudDetectionConfig?

        public init(existingEnrollmentAction: ExistingEnrollmentAction? = nil, fraudDetectionConfig: EnrollmentJobFraudDetectionConfig? = nil) {
            self.existingEnrollmentAction = existingEnrollmentAction
            self.fraudDetectionConfig = fraudDetectionConfig
        }

        public func validate(name: String) throws {
            try self.fraudDetectionConfig?.validate(name: "\(name).fraudDetectionConfig")
        }

        private enum CodingKeys: String, CodingKey {
            case existingEnrollmentAction = "ExistingEnrollmentAction"
            case fraudDetectionConfig = "FraudDetectionConfig"
        }
    }

    public struct EnrollmentJobFraudDetectionConfig: AWSEncodableShape & AWSDecodableShape {
        /// The action to take when the given speaker is flagged by the fraud detection system. The default value is FAIL, which fails the speaker enrollment. Changing this value to IGNORE results in the speaker being enrolled even if they are flagged by the fraud detection system.
        public let fraudDetectionAction: FraudDetectionAction?
        /// Threshold value for determining whether the speaker is a high risk to be fraudulent. If the detected risk score calculated by Voice ID is greater than or equal to the threshold, the speaker is considered a fraudster.
        public let riskThreshold: Int?

        public init(fraudDetectionAction: FraudDetectionAction? = nil, riskThreshold: Int? = nil) {
            self.fraudDetectionAction = fraudDetectionAction
            self.riskThreshold = riskThreshold
        }

        public func validate(name: String) throws {
            try self.validate(self.riskThreshold, name: "riskThreshold", parent: name, max: 100)
            try self.validate(self.riskThreshold, name: "riskThreshold", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case fraudDetectionAction = "FraudDetectionAction"
            case riskThreshold = "RiskThreshold"
        }
    }

    public struct EvaluateSessionRequest: AWSEncodableShape {
        /// The identifier of the domain where the session started.
        public let domainId: String
        /// The session identifier, or name of the session, that you want to evaluate. In Voice ID integration, this is the Contact-Id.
        public let sessionNameOrId: String

        public init(domainId: String, sessionNameOrId: String) {
            self.domainId = domainId
            self.sessionNameOrId = sessionNameOrId
        }

        public func validate(name: String) throws {
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
            try self.validate(self.sessionNameOrId, name: "sessionNameOrId", parent: name, max: 36)
            try self.validate(self.sessionNameOrId, name: "sessionNameOrId", parent: name, min: 1)
            try self.validate(self.sessionNameOrId, name: "sessionNameOrId", parent: name, pattern: "^(id#[a-zA-Z0-9]{22}|[a-zA-Z0-9][a-zA-Z0-9_-]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case domainId = "DomainId"
            case sessionNameOrId = "SessionNameOrId"
        }
    }

    public struct EvaluateSessionResponse: AWSDecodableShape {
        /// Details resulting from the authentication process, such as authentication decision and authentication score.
        public let authenticationResult: AuthenticationResult?
        /// The identifier of the domain containing the session.
        public let domainId: String?
        /// Details resulting from the fraud detection process, such as fraud detection decision and risk score.
        public let fraudDetectionResult: FraudDetectionResult?
        /// The service-generated identifier of the session.
        public let sessionId: String?
        /// The client-provided name of the session.
        public let sessionName: String?
        /// The current status of audio streaming for this session. This field is useful to infer next steps when the Authentication or Fraud Detection results are empty or the decision is NOT_ENOUGH_SPEECH. In this situation, if the StreamingStatus is ONGOING/PENDING_CONFIGURATION, it can mean that the client should call the API again later, after Voice ID has enough audio to produce a result. If the decision remains NOT_ENOUGH_SPEECH even after StreamingStatus is ENDED, it means that the previously streamed session did not have enough speech to perform evaluation, and a new streaming session is needed to try again.
        public let streamingStatus: StreamingStatus?

        public init(authenticationResult: AuthenticationResult? = nil, domainId: String? = nil, fraudDetectionResult: FraudDetectionResult? = nil, sessionId: String? = nil, sessionName: String? = nil, streamingStatus: StreamingStatus? = nil) {
            self.authenticationResult = authenticationResult
            self.domainId = domainId
            self.fraudDetectionResult = fraudDetectionResult
            self.sessionId = sessionId
            self.sessionName = sessionName
            self.streamingStatus = streamingStatus
        }

        private enum CodingKeys: String, CodingKey {
            case authenticationResult = "AuthenticationResult"
            case domainId = "DomainId"
            case fraudDetectionResult = "FraudDetectionResult"
            case sessionId = "SessionId"
            case sessionName = "SessionName"
            case streamingStatus = "StreamingStatus"
        }
    }

    public struct FailureDetails: AWSDecodableShape {
        /// A description of the error that caused the batch job failure.
        public let message: String?
        /// An HTTP status code representing the nature of the error.
        public let statusCode: Int?

        public init(message: String? = nil, statusCode: Int? = nil) {
            self.message = message
            self.statusCode = statusCode
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
            case statusCode = "StatusCode"
        }
    }

    public struct FraudDetectionConfiguration: AWSDecodableShape {
        /// Threshold value for determining whether the speaker is a fraudster. If the detected risk score calculated by Voice ID is higher than the threshold, the speaker is considered a fraudster.
        public let riskThreshold: Int

        public init(riskThreshold: Int) {
            self.riskThreshold = riskThreshold
        }

        private enum CodingKeys: String, CodingKey {
            case riskThreshold = "RiskThreshold"
        }
    }

    public struct FraudDetectionResult: AWSDecodableShape {
        /// A timestamp indicating when audio aggregation ended for this fraud detection result.
        public let audioAggregationEndedAt: Date?
        /// A timestamp indicating when audio aggregation started for this fraud detection result.
        public let audioAggregationStartedAt: Date?
        /// The FraudDetectionConfiguration used to generate this fraud detection result.
        public let configuration: FraudDetectionConfiguration?
        /// The fraud detection decision produced by Voice ID, processed against the current session state and streamed audio of the speaker.
        public let decision: FraudDetectionDecision?
        /// The unique identifier for this fraud detection result. Given there can be multiple fraud detections for a given session, this field helps in identifying if the returned result is from previous streaming activity or a new result. Note that in the absence of any new streaming activity or risk threshold changes, Voice ID always returns cached Fraud Detection result for this API.
        public let fraudDetectionResultId: String?
        /// The reason speaker was flagged by the fraud detection system. This is only be populated if fraud detection Decision is HIGH_RISK, and the following possible values: KNOWN_FRAUDSTER and VOICE_SPOOFING.
        public let reasons: [FraudDetectionReason]?
        /// Details about each risk analyzed for this speaker. Currently, this contains KnownFraudsterRisk and VoiceSpoofingRisk details.
        public let riskDetails: FraudRiskDetails?

        public init(audioAggregationEndedAt: Date? = nil, audioAggregationStartedAt: Date? = nil, configuration: FraudDetectionConfiguration? = nil, decision: FraudDetectionDecision? = nil, fraudDetectionResultId: String? = nil, reasons: [FraudDetectionReason]? = nil, riskDetails: FraudRiskDetails? = nil) {
            self.audioAggregationEndedAt = audioAggregationEndedAt
            self.audioAggregationStartedAt = audioAggregationStartedAt
            self.configuration = configuration
            self.decision = decision
            self.fraudDetectionResultId = fraudDetectionResultId
            self.reasons = reasons
            self.riskDetails = riskDetails
        }

        private enum CodingKeys: String, CodingKey {
            case audioAggregationEndedAt = "AudioAggregationEndedAt"
            case audioAggregationStartedAt = "AudioAggregationStartedAt"
            case configuration = "Configuration"
            case decision = "Decision"
            case fraudDetectionResultId = "FraudDetectionResultId"
            case reasons = "Reasons"
            case riskDetails = "RiskDetails"
        }
    }

    public struct FraudRiskDetails: AWSDecodableShape {
        /// The details resulting from 'Known Fraudster Risk' analysis of the speaker.
        public let knownFraudsterRisk: KnownFraudsterRisk
        /// The details resulting from 'Voice Spoofing Risk' analysis of the speaker.
        public let voiceSpoofingRisk: VoiceSpoofingRisk

        public init(knownFraudsterRisk: KnownFraudsterRisk, voiceSpoofingRisk: VoiceSpoofingRisk) {
            self.knownFraudsterRisk = knownFraudsterRisk
            self.voiceSpoofingRisk = voiceSpoofingRisk
        }

        private enum CodingKeys: String, CodingKey {
            case knownFraudsterRisk = "KnownFraudsterRisk"
            case voiceSpoofingRisk = "VoiceSpoofingRisk"
        }
    }

    public struct Fraudster: AWSDecodableShape {
        /// The timestamp when Voice ID identified the fraudster.
        public let createdAt: Date?
        /// The identifier for the domain containing the fraudster.
        public let domainId: String?
        /// The service-generated identifier for the fraudster.
        public let generatedFraudsterId: String?

        public init(createdAt: Date? = nil, domainId: String? = nil, generatedFraudsterId: String? = nil) {
            self.createdAt = createdAt
            self.domainId = domainId
            self.generatedFraudsterId = generatedFraudsterId
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt = "CreatedAt"
            case domainId = "DomainId"
            case generatedFraudsterId = "GeneratedFraudsterId"
        }
    }

    public struct FraudsterRegistrationJob: AWSDecodableShape {
        /// A timestamp showing the creation time of the fraudster registration job.
        public let createdAt: Date?
        /// The IAM role Amazon Resource Name (ARN) that grants Voice ID permissions to access customer's buckets to read the input manifest file and write the job output file.
        public let dataAccessRoleArn: String?
        /// The identifier of the domain containing the fraudster registration job.
        public let domainId: String?
        /// A timestamp showing when the fraudster registration job ended.
        public let endedAt: Date?
        /// Contains details that are populated when an entire batch job fails. In cases of individual registration job failures, the batch job as a whole doesn't fail; it is completed with a JobStatus of COMPLETED_WITH_ERRORS. You can use the job output file to identify the individual registration requests that failed.
        public let failureDetails: FailureDetails?
        /// The input data config containing an S3 URI for the input manifest file that contains the list of fraudster registration job requests.
        public let inputDataConfig: InputDataConfig?
        /// The service-generated identifier for the fraudster registration job.
        public let jobId: String?
        /// The client-provided name for the fraudster registration job.
        public let jobName: String?
        /// Shows the completed percentage of registration requests listed in the input file.
        public let jobProgress: JobProgress?
        /// The current status of the fraudster registration job.
        public let jobStatus: FraudsterRegistrationJobStatus?
        /// The output data config containing the S3 location where you want Voice ID to write your job output file; you must also include a KMS key ID in order to encrypt the file.
        public let outputDataConfig: OutputDataConfig?
        /// The registration config containing details such as the action to take when a duplicate fraudster is detected, and the similarity threshold to use for detecting a duplicate fraudster.
        public let registrationConfig: RegistrationConfig?

        public init(createdAt: Date? = nil, dataAccessRoleArn: String? = nil, domainId: String? = nil, endedAt: Date? = nil, failureDetails: FailureDetails? = nil, inputDataConfig: InputDataConfig? = nil, jobId: String? = nil, jobName: String? = nil, jobProgress: JobProgress? = nil, jobStatus: FraudsterRegistrationJobStatus? = nil, outputDataConfig: OutputDataConfig? = nil, registrationConfig: RegistrationConfig? = nil) {
            self.createdAt = createdAt
            self.dataAccessRoleArn = dataAccessRoleArn
            self.domainId = domainId
            self.endedAt = endedAt
            self.failureDetails = failureDetails
            self.inputDataConfig = inputDataConfig
            self.jobId = jobId
            self.jobName = jobName
            self.jobProgress = jobProgress
            self.jobStatus = jobStatus
            self.outputDataConfig = outputDataConfig
            self.registrationConfig = registrationConfig
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt = "CreatedAt"
            case dataAccessRoleArn = "DataAccessRoleArn"
            case domainId = "DomainId"
            case endedAt = "EndedAt"
            case failureDetails = "FailureDetails"
            case inputDataConfig = "InputDataConfig"
            case jobId = "JobId"
            case jobName = "JobName"
            case jobProgress = "JobProgress"
            case jobStatus = "JobStatus"
            case outputDataConfig = "OutputDataConfig"
            case registrationConfig = "RegistrationConfig"
        }
    }

    public struct FraudsterRegistrationJobSummary: AWSDecodableShape {
        /// A timestamp showing when the fraudster registration job is created.
        public let createdAt: Date?
        /// The identifier of the domain containing the fraudster registration job.
        public let domainId: String?
        /// A timestamp showing when the fraudster registration job ended.
        public let endedAt: Date?
        /// Contains details that are populated when an entire batch job fails. In cases of individual registration job failures, the batch job as a whole doesn't fail; it is completed with a JobStatus of COMPLETED_WITH_ERRORS. You can use the job output file to identify the individual registration requests that failed.
        public let failureDetails: FailureDetails?
        /// The service-generated identifier for the fraudster registration job.
        public let jobId: String?
        /// The client-provided name for the fraudster registration job.
        public let jobName: String?
        /// Shows the completed percentage of registration requests listed in the input file.
        public let jobProgress: JobProgress?
        /// The current status of the fraudster registration job.
        public let jobStatus: FraudsterRegistrationJobStatus?

        public init(createdAt: Date? = nil, domainId: String? = nil, endedAt: Date? = nil, failureDetails: FailureDetails? = nil, jobId: String? = nil, jobName: String? = nil, jobProgress: JobProgress? = nil, jobStatus: FraudsterRegistrationJobStatus? = nil) {
            self.createdAt = createdAt
            self.domainId = domainId
            self.endedAt = endedAt
            self.failureDetails = failureDetails
            self.jobId = jobId
            self.jobName = jobName
            self.jobProgress = jobProgress
            self.jobStatus = jobStatus
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt = "CreatedAt"
            case domainId = "DomainId"
            case endedAt = "EndedAt"
            case failureDetails = "FailureDetails"
            case jobId = "JobId"
            case jobName = "JobName"
            case jobProgress = "JobProgress"
            case jobStatus = "JobStatus"
        }
    }

    public struct InputDataConfig: AWSEncodableShape & AWSDecodableShape {
        /// The S3 location for the input manifest file that contains the list of individual enrollment or registration job requests.
        public let s3Uri: String

        public init(s3Uri: String) {
            self.s3Uri = s3Uri
        }

        public func validate(name: String) throws {
            try self.validate(self.s3Uri, name: "s3Uri", parent: name, max: 1024)
            try self.validate(self.s3Uri, name: "s3Uri", parent: name, pattern: "^s3://[a-z0-9][\\.\\-a-z0-9]{1,61}[a-z0-9](/.*)?$")
        }

        private enum CodingKeys: String, CodingKey {
            case s3Uri = "S3Uri"
        }
    }

    public struct JobProgress: AWSDecodableShape {
        /// Shows the completed percentage of enrollment or registration requests listed in the input file.
        public let percentComplete: Int?

        public init(percentComplete: Int? = nil) {
            self.percentComplete = percentComplete
        }

        private enum CodingKeys: String, CodingKey {
            case percentComplete = "PercentComplete"
        }
    }

    public struct KnownFraudsterRisk: AWSDecodableShape {
        /// The identifier of the fraudster that is the closest match to the speaker. If there are no fraudsters registered in a given domain, or if there are no fraudsters with a non-zero RiskScore, this value is null.
        public let generatedFraudsterId: String?
        /// The score indicating the likelihood the speaker is a known fraudster.
        public let riskScore: Int

        public init(generatedFraudsterId: String? = nil, riskScore: Int) {
            self.generatedFraudsterId = generatedFraudsterId
            self.riskScore = riskScore
        }

        private enum CodingKeys: String, CodingKey {
            case generatedFraudsterId = "GeneratedFraudsterId"
            case riskScore = "RiskScore"
        }
    }

    public struct ListDomainsRequest: AWSEncodableShape {
        /// The maximum number of domains to list per API call.
        public let maxResults: Int?
        /// If NextToken is returned, there are more results available. The value of NextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged. Each pagination token expires after 24 hours.
        public let nextToken: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 10)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^\\p{ASCII}{0,8192}$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListDomainsResponse: AWSDecodableShape {
        /// A list containing details about each domain in the Amazon Web Services account.
        public let domainSummaries: [DomainSummary]?
        /// If NextToken is returned, there are more results available. The value of NextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged. Each pagination token expires after 24 hours.
        public let nextToken: String?

        public init(domainSummaries: [DomainSummary]? = nil, nextToken: String? = nil) {
            self.domainSummaries = domainSummaries
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case domainSummaries = "DomainSummaries"
            case nextToken = "NextToken"
        }
    }

    public struct ListFraudsterRegistrationJobsRequest: AWSEncodableShape {
        /// The identifier of the domain containing the fraudster registration Jobs.
        public let domainId: String
        /// Provides the status of your fraudster registration job.
        public let jobStatus: FraudsterRegistrationJobStatus?
        /// The maximum number of results that are returned per call. You can use NextToken to obtain further pages of results. The default is 100; the maximum allowed page size is also 100.
        public let maxResults: Int?
        /// If NextToken is returned, there are more results available. The value of NextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged. Each pagination token expires after 24 hours.
        public let nextToken: String?

        public init(domainId: String, jobStatus: FraudsterRegistrationJobStatus? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.domainId = domainId
            self.jobStatus = jobStatus
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^\\p{ASCII}{0,8192}$")
        }

        private enum CodingKeys: String, CodingKey {
            case domainId = "DomainId"
            case jobStatus = "JobStatus"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListFraudsterRegistrationJobsResponse: AWSDecodableShape {
        /// A list containing details about each specified fraudster registration job.
        public let jobSummaries: [FraudsterRegistrationJobSummary]?
        /// If NextToken is returned, there are more results available. The value of NextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged. Each pagination token expires after 24 hours.
        public let nextToken: String?

        public init(jobSummaries: [FraudsterRegistrationJobSummary]? = nil, nextToken: String? = nil) {
            self.jobSummaries = jobSummaries
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case jobSummaries = "JobSummaries"
            case nextToken = "NextToken"
        }
    }

    public struct ListSpeakerEnrollmentJobsRequest: AWSEncodableShape {
        /// The identifier of the domain containing the speaker enrollment jobs.
        public let domainId: String
        /// Provides the status of your speaker enrollment Job.
        public let jobStatus: SpeakerEnrollmentJobStatus?
        /// The maximum number of results that are returned per call. You can use NextToken to obtain further pages of results. The default is 100; the maximum allowed page size is also 100.
        public let maxResults: Int?
        /// If NextToken is returned, there are more results available. The value of NextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged. Each pagination token expires after 24 hours.
        public let nextToken: String?

        public init(domainId: String, jobStatus: SpeakerEnrollmentJobStatus? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.domainId = domainId
            self.jobStatus = jobStatus
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^\\p{ASCII}{0,8192}$")
        }

        private enum CodingKeys: String, CodingKey {
            case domainId = "DomainId"
            case jobStatus = "JobStatus"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListSpeakerEnrollmentJobsResponse: AWSDecodableShape {
        /// A list containing details about each specified speaker enrollment job.
        public let jobSummaries: [SpeakerEnrollmentJobSummary]?
        /// If NextToken is returned, there are more results available. The value of NextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged. Each pagination token expires after 24 hours.
        public let nextToken: String?

        public init(jobSummaries: [SpeakerEnrollmentJobSummary]? = nil, nextToken: String? = nil) {
            self.jobSummaries = jobSummaries
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case jobSummaries = "JobSummaries"
            case nextToken = "NextToken"
        }
    }

    public struct ListSpeakersRequest: AWSEncodableShape {
        /// The identifier of the domain.
        public let domainId: String
        /// The maximum number of results that are returned per call. You can use NextToken to obtain further pages of results. The default is 100; the maximum allowed page size is also 100.
        public let maxResults: Int?
        /// If NextToken is returned, there are more results available. The value of NextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged. Each pagination token expires after 24 hours.
        public let nextToken: String?

        public init(domainId: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.domainId = domainId
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 8192)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^\\p{ASCII}{0,8192}$")
        }

        private enum CodingKeys: String, CodingKey {
            case domainId = "DomainId"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListSpeakersResponse: AWSDecodableShape {
        /// If NextToken is returned, there are more results available. The value of NextToken is a unique pagination token for each page. Make the call again using the returned token to retrieve the next page. Keep all other arguments unchanged. Each pagination token expires after 24 hours.
        public let nextToken: String?
        /// A list containing details about each speaker in the Amazon Web Services account.
        public let speakerSummaries: [SpeakerSummary]?

        public init(nextToken: String? = nil, speakerSummaries: [SpeakerSummary]? = nil) {
            self.nextToken = nextToken
            self.speakerSummaries = speakerSummaries
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case speakerSummaries = "SpeakerSummaries"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the Voice ID resource for which you want to list the tags.
        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws(-[^:]+)?:voiceid.+:[0-9]{12}:domain/[a-zA-Z0-9]{22}$")
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
        }
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// The list of tags associated with the specified resource.
        public let tags: [Tag]?

        public init(tags: [Tag]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct OptOutSpeakerRequest: AWSEncodableShape {
        /// The identifier of the domain containing the speaker.
        public let domainId: String
        /// The identifier of the speaker you want opted-out.
        public let speakerId: String

        public init(domainId: String, speakerId: String) {
            self.domainId = domainId
            self.speakerId = speakerId
        }

        public func validate(name: String) throws {
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
            try self.validate(self.speakerId, name: "speakerId", parent: name, max: 256)
            try self.validate(self.speakerId, name: "speakerId", parent: name, min: 1)
            try self.validate(self.speakerId, name: "speakerId", parent: name, pattern: "^(id#[a-zA-Z0-9]{22}|[a-zA-Z0-9][a-zA-Z0-9_-]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case domainId = "DomainId"
            case speakerId = "SpeakerId"
        }
    }

    public struct OptOutSpeakerResponse: AWSDecodableShape {
        /// Details about the opted-out speaker.
        public let speaker: Speaker?

        public init(speaker: Speaker? = nil) {
            self.speaker = speaker
        }

        private enum CodingKeys: String, CodingKey {
            case speaker = "Speaker"
        }
    }

    public struct OutputDataConfig: AWSEncodableShape & AWSDecodableShape {
        /// The identifier of the KMS key you want Voice ID to use to encrypt the output file of a speaker enrollment job/fraudster registration job.
        public let kmsKeyId: String?
        /// The S3 path of the folder where Voice ID writes the job output file. It has a *.out extension. For example, if the input file name is input-file.json and the output folder path is s3://output-bucket/output-folder, the full output file path is s3://output-bucket/output-folder/job-Id/input-file.json.out.
        public let s3Uri: String

        public init(kmsKeyId: String? = nil, s3Uri: String) {
            self.kmsKeyId = kmsKeyId
            self.s3Uri = s3Uri
        }

        public func validate(name: String) throws {
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, max: 2048)
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, min: 1)
            try self.validate(self.s3Uri, name: "s3Uri", parent: name, max: 1024)
            try self.validate(self.s3Uri, name: "s3Uri", parent: name, pattern: "^s3://[a-z0-9][\\.\\-a-z0-9]{1,61}[a-z0-9](/.*)?$")
        }

        private enum CodingKeys: String, CodingKey {
            case kmsKeyId = "KmsKeyId"
            case s3Uri = "S3Uri"
        }
    }

    public struct RegistrationConfig: AWSEncodableShape & AWSDecodableShape {
        /// The action to take when a fraudster is identified as a duplicate. The default action is SKIP, which skips registering the duplicate fraudster. Setting the value to REGISTER_AS_NEW always registers a new fraudster into the specified domain.
        public let duplicateRegistrationAction: DuplicateRegistrationAction?
        /// The minimum similarity score between the new and old fraudsters in order to consider the new fraudster a duplicate.
        public let fraudsterSimilarityThreshold: Int?

        public init(duplicateRegistrationAction: DuplicateRegistrationAction? = nil, fraudsterSimilarityThreshold: Int? = nil) {
            self.duplicateRegistrationAction = duplicateRegistrationAction
            self.fraudsterSimilarityThreshold = fraudsterSimilarityThreshold
        }

        public func validate(name: String) throws {
            try self.validate(self.fraudsterSimilarityThreshold, name: "fraudsterSimilarityThreshold", parent: name, max: 100)
            try self.validate(self.fraudsterSimilarityThreshold, name: "fraudsterSimilarityThreshold", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case duplicateRegistrationAction = "DuplicateRegistrationAction"
            case fraudsterSimilarityThreshold = "FraudsterSimilarityThreshold"
        }
    }

    public struct ServerSideEncryptionConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// The identifier of the KMS key to use to encrypt data stored by Voice ID. Voice ID doesn't support asymmetric customer managed keys.
        public let kmsKeyId: String

        public init(kmsKeyId: String) {
            self.kmsKeyId = kmsKeyId
        }

        public func validate(name: String) throws {
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, max: 2048)
            try self.validate(self.kmsKeyId, name: "kmsKeyId", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case kmsKeyId = "KmsKeyId"
        }
    }

    public struct ServerSideEncryptionUpdateDetails: AWSDecodableShape {
        /// Message explaining the current UpdateStatus. When the UpdateStatus is FAILED, this message explains the cause of the failure.
        public let message: String?
        /// The previous KMS key ID the domain was encrypted with, before ServerSideEncryptionConfiguration was updated to a new KMS key ID.
        public let oldKmsKeyId: String?
        /// Status of the server-side encryption update. During an update, if there is an issue with the domain's current or old KMS key ID, such as an inaccessible or disabled key, then the status is FAILED. In order to resolve this, the key needs to be made accessible, and then an UpdateDomain call with the existing server-side encryption configuration will re-attempt this update process.
        public let updateStatus: ServerSideEncryptionUpdateStatus?

        public init(message: String? = nil, oldKmsKeyId: String? = nil, updateStatus: ServerSideEncryptionUpdateStatus? = nil) {
            self.message = message
            self.oldKmsKeyId = oldKmsKeyId
            self.updateStatus = updateStatus
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
            case oldKmsKeyId = "OldKmsKeyId"
            case updateStatus = "UpdateStatus"
        }
    }

    public struct Speaker: AWSDecodableShape {
        /// A timestamp showing when the speaker is created.
        public let createdAt: Date?
        /// The client-provided identifier for the speaker.
        public let customerSpeakerId: String?
        /// The identifier of the domain that contains the speaker.
        public let domainId: String?
        /// The service-generated identifier for the speaker.
        public let generatedSpeakerId: String?
        /// The timestamp when the speaker was last accessed for enrollment, re-enrollment or a successful authentication. This timestamp is accurate to one hour.
        public let lastAccessedAt: Date?
        /// The current status of the speaker.
        public let status: SpeakerStatus?
        /// A timestamp showing the speaker's last update.
        public let updatedAt: Date?

        public init(createdAt: Date? = nil, customerSpeakerId: String? = nil, domainId: String? = nil, generatedSpeakerId: String? = nil, lastAccessedAt: Date? = nil, status: SpeakerStatus? = nil, updatedAt: Date? = nil) {
            self.createdAt = createdAt
            self.customerSpeakerId = customerSpeakerId
            self.domainId = domainId
            self.generatedSpeakerId = generatedSpeakerId
            self.lastAccessedAt = lastAccessedAt
            self.status = status
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt = "CreatedAt"
            case customerSpeakerId = "CustomerSpeakerId"
            case domainId = "DomainId"
            case generatedSpeakerId = "GeneratedSpeakerId"
            case lastAccessedAt = "LastAccessedAt"
            case status = "Status"
            case updatedAt = "UpdatedAt"
        }
    }

    public struct SpeakerEnrollmentJob: AWSDecodableShape {
        /// A timestamp showing the creation of the speaker enrollment job.
        public let createdAt: Date?
        /// The IAM role Amazon Resource Name (ARN) that grants Voice ID permissions to access customer's buckets to read the input manifest file and write the job output file.
        public let dataAccessRoleArn: String?
        /// The identifier of the domain that contains the speaker enrollment job.
        public let domainId: String?
        /// A timestamp showing when the speaker enrollment job ended.
        public let endedAt: Date?
        /// The configuration that defines the action to take when the speaker is already enrolled in Voice ID, and the FraudDetectionConfig to use.
        public let enrollmentConfig: EnrollmentConfig?
        /// Contains details that are populated when an entire batch job fails. In cases of individual registration job failures, the batch job as a whole doesn't fail; it is completed with a JobStatus of COMPLETED_WITH_ERRORS. You can use the job output file to identify the individual registration requests that failed.
        public let failureDetails: FailureDetails?
        /// The input data config containing an S3 URI for the input manifest file that contains the list of speaker enrollment job requests.
        public let inputDataConfig: InputDataConfig?
        /// The service-generated identifier for the speaker enrollment job.
        public let jobId: String?
        /// The client-provided name for the speaker enrollment job.
        public let jobName: String?
        /// Provides details on job progress. This field shows the completed percentage of registration requests listed in the input file.
        public let jobProgress: JobProgress?
        /// The current status of the speaker enrollment job.
        public let jobStatus: SpeakerEnrollmentJobStatus?
        /// The output data config containing the S3 location where Voice ID writes the job output file; you must also include a KMS key ID to encrypt the file.
        public let outputDataConfig: OutputDataConfig?

        public init(createdAt: Date? = nil, dataAccessRoleArn: String? = nil, domainId: String? = nil, endedAt: Date? = nil, enrollmentConfig: EnrollmentConfig? = nil, failureDetails: FailureDetails? = nil, inputDataConfig: InputDataConfig? = nil, jobId: String? = nil, jobName: String? = nil, jobProgress: JobProgress? = nil, jobStatus: SpeakerEnrollmentJobStatus? = nil, outputDataConfig: OutputDataConfig? = nil) {
            self.createdAt = createdAt
            self.dataAccessRoleArn = dataAccessRoleArn
            self.domainId = domainId
            self.endedAt = endedAt
            self.enrollmentConfig = enrollmentConfig
            self.failureDetails = failureDetails
            self.inputDataConfig = inputDataConfig
            self.jobId = jobId
            self.jobName = jobName
            self.jobProgress = jobProgress
            self.jobStatus = jobStatus
            self.outputDataConfig = outputDataConfig
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt = "CreatedAt"
            case dataAccessRoleArn = "DataAccessRoleArn"
            case domainId = "DomainId"
            case endedAt = "EndedAt"
            case enrollmentConfig = "EnrollmentConfig"
            case failureDetails = "FailureDetails"
            case inputDataConfig = "InputDataConfig"
            case jobId = "JobId"
            case jobName = "JobName"
            case jobProgress = "JobProgress"
            case jobStatus = "JobStatus"
            case outputDataConfig = "OutputDataConfig"
        }
    }

    public struct SpeakerEnrollmentJobSummary: AWSDecodableShape {
        /// A timestamp showing the creation time of the speaker enrollment job.
        public let createdAt: Date?
        /// The identifier of the domain that contains the speaker enrollment job.
        public let domainId: String?
        /// A timestamp showing when the speaker enrollment job ended.
        public let endedAt: Date?
        /// Contains details that are populated when an entire batch job fails. In cases of individual registration job failures, the batch job as a whole doesn't fail; it is completed with a JobStatus of COMPLETED_WITH_ERRORS. You can use the job output file to identify the individual registration requests that failed.
        public let failureDetails: FailureDetails?
        /// The service-generated identifier for the speaker enrollment job.
        public let jobId: String?
        /// The client-provided name for the speaker enrollment job.
        public let jobName: String?
        /// Provides details regarding job progress. This field shows the completed percentage of enrollment requests listed in the input file.
        public let jobProgress: JobProgress?
        /// The current status of the speaker enrollment job.
        public let jobStatus: SpeakerEnrollmentJobStatus?

        public init(createdAt: Date? = nil, domainId: String? = nil, endedAt: Date? = nil, failureDetails: FailureDetails? = nil, jobId: String? = nil, jobName: String? = nil, jobProgress: JobProgress? = nil, jobStatus: SpeakerEnrollmentJobStatus? = nil) {
            self.createdAt = createdAt
            self.domainId = domainId
            self.endedAt = endedAt
            self.failureDetails = failureDetails
            self.jobId = jobId
            self.jobName = jobName
            self.jobProgress = jobProgress
            self.jobStatus = jobStatus
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt = "CreatedAt"
            case domainId = "DomainId"
            case endedAt = "EndedAt"
            case failureDetails = "FailureDetails"
            case jobId = "JobId"
            case jobName = "JobName"
            case jobProgress = "JobProgress"
            case jobStatus = "JobStatus"
        }
    }

    public struct SpeakerSummary: AWSDecodableShape {
        /// A timestamp showing the speaker's creation time.
        public let createdAt: Date?
        /// The client-provided identifier for the speaker.
        public let customerSpeakerId: String?
        /// The identifier of the domain that contains the speaker.
        public let domainId: String?
        /// The service-generated identifier for the speaker.
        public let generatedSpeakerId: String?
        /// The timestamp when the speaker was last accessed for enrollment, re-enrollment or a successful authentication. This timestamp is accurate to one hour.
        public let lastAccessedAt: Date?
        /// The current status of the speaker.
        public let status: SpeakerStatus?
        /// A timestamp showing the speaker's last update.
        public let updatedAt: Date?

        public init(createdAt: Date? = nil, customerSpeakerId: String? = nil, domainId: String? = nil, generatedSpeakerId: String? = nil, lastAccessedAt: Date? = nil, status: SpeakerStatus? = nil, updatedAt: Date? = nil) {
            self.createdAt = createdAt
            self.customerSpeakerId = customerSpeakerId
            self.domainId = domainId
            self.generatedSpeakerId = generatedSpeakerId
            self.lastAccessedAt = lastAccessedAt
            self.status = status
            self.updatedAt = updatedAt
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt = "CreatedAt"
            case customerSpeakerId = "CustomerSpeakerId"
            case domainId = "DomainId"
            case generatedSpeakerId = "GeneratedSpeakerId"
            case lastAccessedAt = "LastAccessedAt"
            case status = "Status"
            case updatedAt = "UpdatedAt"
        }
    }

    public struct StartFraudsterRegistrationJobRequest: AWSEncodableShape {
        /// The idempotency token for starting a new fraudster registration job. If not provided, Amazon Web Services SDK populates this field.
        public let clientToken: String?
        /// The IAM role Amazon Resource Name (ARN) that grants Voice ID permissions to access customer's buckets to read the input manifest file and write the Job output file. Refer to the Create and edit a fraudster watchlist documentation for the permissions needed in this role.
        public let dataAccessRoleArn: String
        /// The identifier of the domain containing the fraudster registration job and in which the fraudsters are registered.
        public let domainId: String
        /// The input data config containing an S3 URI for the input manifest file that contains the list of fraudster registration requests.
        public let inputDataConfig: InputDataConfig
        /// The name of the new fraudster registration job.
        public let jobName: String?
        /// The output data config containing the S3 location where Voice ID writes the job output file; you must also include a KMS key ID to encrypt the file.
        public let outputDataConfig: OutputDataConfig
        /// The registration config containing details such as the action to take when a duplicate fraudster is detected, and the similarity threshold to use for detecting a duplicate fraudster.
        public let registrationConfig: RegistrationConfig?

        public init(clientToken: String? = StartFraudsterRegistrationJobRequest.idempotencyToken(), dataAccessRoleArn: String, domainId: String, inputDataConfig: InputDataConfig, jobName: String? = nil, outputDataConfig: OutputDataConfig, registrationConfig: RegistrationConfig? = nil) {
            self.clientToken = clientToken
            self.dataAccessRoleArn = dataAccessRoleArn
            self.domainId = domainId
            self.inputDataConfig = inputDataConfig
            self.jobName = jobName
            self.outputDataConfig = outputDataConfig
            self.registrationConfig = registrationConfig
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[a-zA-Z0-9-_]+$")
            try self.validate(self.dataAccessRoleArn, name: "dataAccessRoleArn", parent: name, max: 2048)
            try self.validate(self.dataAccessRoleArn, name: "dataAccessRoleArn", parent: name, min: 20)
            try self.validate(self.dataAccessRoleArn, name: "dataAccessRoleArn", parent: name, pattern: "^arn:aws(-[^:]+)?:iam::[0-9]{12}:role/.+$")
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
            try self.inputDataConfig.validate(name: "\(name).inputDataConfig")
            try self.validate(self.jobName, name: "jobName", parent: name, max: 256)
            try self.validate(self.jobName, name: "jobName", parent: name, min: 1)
            try self.validate(self.jobName, name: "jobName", parent: name, pattern: "^[a-zA-Z0-9][a-zA-Z0-9_-]*$")
            try self.outputDataConfig.validate(name: "\(name).outputDataConfig")
            try self.registrationConfig?.validate(name: "\(name).registrationConfig")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case dataAccessRoleArn = "DataAccessRoleArn"
            case domainId = "DomainId"
            case inputDataConfig = "InputDataConfig"
            case jobName = "JobName"
            case outputDataConfig = "OutputDataConfig"
            case registrationConfig = "RegistrationConfig"
        }
    }

    public struct StartFraudsterRegistrationJobResponse: AWSDecodableShape {
        /// Details about the started fraudster registration job.
        public let job: FraudsterRegistrationJob?

        public init(job: FraudsterRegistrationJob? = nil) {
            self.job = job
        }

        private enum CodingKeys: String, CodingKey {
            case job = "Job"
        }
    }

    public struct StartSpeakerEnrollmentJobRequest: AWSEncodableShape {
        /// The idempotency token for starting a new speaker enrollment Job. If not provided, Amazon Web Services SDK populates this field.
        public let clientToken: String?
        /// The IAM role Amazon Resource Name (ARN) that grants Voice ID permissions to access customer's buckets to read the input manifest file and write the job output file. Refer to Batch enrollment using audio data from prior calls for the permissions needed in this role.
        public let dataAccessRoleArn: String
        /// The identifier of the domain that contains the speaker enrollment job and in which the speakers are enrolled.
        public let domainId: String
        /// The enrollment config that contains details such as the action to take when a speaker is already enrolled in Voice ID or when a speaker is identified as a fraudster.
        public let enrollmentConfig: EnrollmentConfig?
        /// The input data config containing the S3 location for the input manifest file that contains the list of speaker enrollment requests.
        public let inputDataConfig: InputDataConfig
        /// A name for your speaker enrollment job.
        public let jobName: String?
        /// The output data config containing the S3 location where Voice ID writes the job output file; you must also include a KMS key ID to encrypt the file.
        public let outputDataConfig: OutputDataConfig

        public init(clientToken: String? = StartSpeakerEnrollmentJobRequest.idempotencyToken(), dataAccessRoleArn: String, domainId: String, enrollmentConfig: EnrollmentConfig? = nil, inputDataConfig: InputDataConfig, jobName: String? = nil, outputDataConfig: OutputDataConfig) {
            self.clientToken = clientToken
            self.dataAccessRoleArn = dataAccessRoleArn
            self.domainId = domainId
            self.enrollmentConfig = enrollmentConfig
            self.inputDataConfig = inputDataConfig
            self.jobName = jobName
            self.outputDataConfig = outputDataConfig
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, max: 64)
            try self.validate(self.clientToken, name: "clientToken", parent: name, min: 1)
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[a-zA-Z0-9-_]+$")
            try self.validate(self.dataAccessRoleArn, name: "dataAccessRoleArn", parent: name, max: 2048)
            try self.validate(self.dataAccessRoleArn, name: "dataAccessRoleArn", parent: name, min: 20)
            try self.validate(self.dataAccessRoleArn, name: "dataAccessRoleArn", parent: name, pattern: "^arn:aws(-[^:]+)?:iam::[0-9]{12}:role/.+$")
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
            try self.enrollmentConfig?.validate(name: "\(name).enrollmentConfig")
            try self.inputDataConfig.validate(name: "\(name).inputDataConfig")
            try self.validate(self.jobName, name: "jobName", parent: name, max: 256)
            try self.validate(self.jobName, name: "jobName", parent: name, min: 1)
            try self.validate(self.jobName, name: "jobName", parent: name, pattern: "^[a-zA-Z0-9][a-zA-Z0-9_-]*$")
            try self.outputDataConfig.validate(name: "\(name).outputDataConfig")
        }

        private enum CodingKeys: String, CodingKey {
            case clientToken = "ClientToken"
            case dataAccessRoleArn = "DataAccessRoleArn"
            case domainId = "DomainId"
            case enrollmentConfig = "EnrollmentConfig"
            case inputDataConfig = "InputDataConfig"
            case jobName = "JobName"
            case outputDataConfig = "OutputDataConfig"
        }
    }

    public struct StartSpeakerEnrollmentJobResponse: AWSDecodableShape {
        /// Details about the started speaker enrollment job.
        public let job: SpeakerEnrollmentJob?

        public init(job: SpeakerEnrollmentJob? = nil) {
            self.job = job
        }

        private enum CodingKeys: String, CodingKey {
            case job = "Job"
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// The first part of a key:value pair that forms a tag associated with a given resource. For example, in the tag 'Department':'Sales', the key is 'Department'.
        public let key: String
        /// The second part of a key:value pair that forms a tag associated with a given resource. For example, in the tag 'Department':'Sales', the value is 'Sales'.
        public let value: String

        public init(key: String, value: String) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.key, name: "key", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the Voice ID resource you want to tag.
        public let resourceArn: String
        /// The list of tags to assign to the specified resource.
        public let tags: [Tag]

        public init(resourceArn: String, tags: [Tag]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws(-[^:]+)?:voiceid.+:[0-9]{12}:domain/[a-zA-Z0-9]{22}$")
            try self.tags.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
            case tags = "Tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the Voice ID resource you want to remove tags from.
        public let resourceArn: String
        /// The list of tag keys you want to remove from the specified resource.
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1011)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws(-[^:]+)?:voiceid.+:[0-9]{12}:domain/[a-zA-Z0-9]{22}$")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
                try validate($0, name: "tagKeys[]", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]*)$")
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 200)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
            case tagKeys = "TagKeys"
        }
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateDomainRequest: AWSEncodableShape {
        /// A brief description of the domain.
        public let description: String?
        /// The identifier of the domain to be updated.
        public let domainId: String
        /// The name of the domain.
        public let name: String
        /// The configuration, containing the KMS key identifier, to be used by Voice ID for the server-side encryption of your data. Changing the domain's associated KMS key immediately triggers an asynchronous process to remove dependency on the old KMS key, such that the domain's data can only be accessed using the new KMS key. The domain's ServerSideEncryptionUpdateDetails contains the details for this process.
        public let serverSideEncryptionConfiguration: ServerSideEncryptionConfiguration

        public init(description: String? = nil, domainId: String, name: String, serverSideEncryptionConfiguration: ServerSideEncryptionConfiguration) {
            self.description = description
            self.domainId = domainId
            self.name = name
            self.serverSideEncryptionConfiguration = serverSideEncryptionConfiguration
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 1024)
            try self.validate(self.description, name: "description", parent: name, min: 1)
            try self.validate(self.description, name: "description", parent: name, pattern: "^([\\p{L}\\p{Z}\\p{N}_.:/=+\\-%@]*)$")
            try self.validate(self.domainId, name: "domainId", parent: name, max: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, min: 22)
            try self.validate(self.domainId, name: "domainId", parent: name, pattern: "^[a-zA-Z0-9]{22}$")
            try self.validate(self.name, name: "name", parent: name, max: 256)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9][a-zA-Z0-9_-]*$")
            try self.serverSideEncryptionConfiguration.validate(name: "\(name).serverSideEncryptionConfiguration")
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case domainId = "DomainId"
            case name = "Name"
            case serverSideEncryptionConfiguration = "ServerSideEncryptionConfiguration"
        }
    }

    public struct UpdateDomainResponse: AWSDecodableShape {
        /// Details about the updated domain
        public let domain: Domain?

        public init(domain: Domain? = nil) {
            self.domain = domain
        }

        private enum CodingKeys: String, CodingKey {
            case domain = "Domain"
        }
    }

    public struct VoiceSpoofingRisk: AWSDecodableShape {
        /// The score indicating the likelihood of speaker’s voice being spoofed.
        public let riskScore: Int

        public init(riskScore: Int) {
            self.riskScore = riskScore
        }

        private enum CodingKeys: String, CodingKey {
            case riskScore = "RiskScore"
        }
    }
}

// MARK: - Errors

/// Error enum for VoiceID
public struct VoiceIDErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize VoiceID
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You do not have sufficient permissions to perform this action. Check the error message and try again.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// The request failed due to a conflict. Check the ConflictType and error message for more details.
    public static var conflictException: Self { .init(.conflictException) }
    /// The request failed due to an unknown error on the server side.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// The specified resource cannot be found. Check the ResourceType and error message for more details.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// The request exceeded the service quota. Refer to Voice ID Service Quotas and try your request again.
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    /// The request was denied due to request throttling. Please slow down your request rate. Refer to  Amazon Connect Voice ID Service API throttling quotas  and try your request again.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// The request failed one or more validations; check the error message for more details.
    public static var validationException: Self { .init(.validationException) }
}

extension VoiceIDErrorType: Equatable {
    public static func == (lhs: VoiceIDErrorType, rhs: VoiceIDErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension VoiceIDErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
